use crate::prelude::*;
// usize在64位机器上就是64位,在32位机器上就是32位,通常使用unsize作为集合和数组的索引
const NUM_TILES: usize = ( SCREEN_WIDTH * SCREEN_HEIGHT) as usize;  


// 枚举:定义每个图块的类型，图块要么表示墙,要么表示地板
// 增加宏,Clone为类型增加一个clone函数,Copy为类型增加一个copy函数，PartialEq可以使用==操作符来比较两个类型是否相同
#[derive(Clone, Copy, PartialEq)]
pub enum TileType {
    Wall,
    Floor,
}

pub struct Map {
    pub tiles: Vec<TileType>,   // 动态数组
}

// 为地图创建索引,二维数组索引转为一维向量索引
pub fn map_idx(x:i32,y:i32) -> usize {
    let index = (y * SCREEN_WIDTH) + x;       
    // 将结果转换为usize
    index as usize
}

impl Map {
    pub fn new() -> Self {
        Self {
            tiles:vec![TileType::Floor; NUM_TILES]   // 创建一个完全由地板组成的地图
        }
    }

    // 渲染地图
    pub fn render(&self, ctx:&mut BTerm) {
        for y in 0..SCREEN_HEIGHT {
            for x in 0..SCREEN_WIDTH {
                let idx = map_idx(x, y);
                match self.tiles[idx] {
                    TileType::Floor => {
                        ctx.set(x,y,YELLOW, BLACK, to_cp437('.'))
                    }
                    TileType::Wall => {
                        ctx.set(x,y,YELLOW, BLACK, to_cp437('#'))
                    }
                }
            }
        }
    }

}

pub struct State {
    map:Map,
}

impl State {
    pub fn new() -> Self {
        Self {map:Map::new()}
    }
}

impl GameState for State {
    fn tick(&mut self, ctx: &mut BTerm) {
        ctx.cls();
        self.map.render(ctx)
    }
}
